package org.xm.sk.service.data.impl;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xm.sk.dao.UserRepository;
import org.xm.sk.service.data.BaseService;
import org.xm.sk.vo.User;

@Service
@Transactional
public class UserServiceImpl implements BaseService<User> {

    private static final String CACHE_KEY = "'user'";
    private static final String sk_CACHE_NAME = "users";

    @Autowired
    private UserRepository userRepository;

    @Cacheable(value = sk_CACHE_NAME, key = CACHE_KEY + "'_'+#p0")
    public User findById(int id) {
        return this.userRepository.findOne(id);
    }

    @Cacheable(value = sk_CACHE_NAME, key = CACHE_KEY + "'_'+#p0")
    public Set<User> findByName(String name) {
        return this.userRepository.findByName(name);
    }

    @Cacheable(value = sk_CACHE_NAME, key = CACHE_KEY + "'_all'")
    public List<User> findAll() {
        return this.userRepository.findAll();
    }

    @Cacheable(value = sk_CACHE_NAME, key = CACHE_KEY + "'_'+#p0")
    public List<User> findAll(User user) {
        ExampleMatcher matcher = ExampleMatcher.matchingAny();
        Example<User> ex = Example.of(user, matcher);
        return this.userRepository.findAll(ex);
    }

    @Cacheable(value = sk_CACHE_NAME, key = CACHE_KEY + "'_'+#p0+'_'+#p1")
    public List<User> findAllByPage(int page, int size) {
        Pageable pageable = new PageRequest(page, size);
        Page<User> users = this.userRepository.findAll(pageable);
        return users.getContent();
    }

    @CacheEvict(value = sk_CACHE_NAME, allEntries=true)
    //@CachePut(value = sk_CACHE_NAME, key = CACHE_KEY + "'_'+#p0.id")
    public User update(User user) {
        return this.userRepository.save(user);
    }

    @CacheEvict(value = sk_CACHE_NAME, allEntries=true)
    public void delete(int id) {
        this.userRepository.delete(id);
    }

    @CacheEvict(value = sk_CACHE_NAME, allEntries=true)
    public User add(User user) {
        return this.userRepository.saveAndFlush(user);
    }

}